package com.unbank.search;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.elasticsearch.action.mlt.MoreLikeThisRequestBuilder;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortOrder;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.unbank.entity.News;
import com.unbank.values.SysParameters;

public class SearchClient {

	private static final String INDEXNAME = SysParameters.INDEXNAME;

	/**
	 * 鎸夌収璇嶈鎼滅储
	 * 
	 * @param word
	 * @param sizeFrom
	 * @param size
	 * @return
	 */
	public List<News> SearchByWord(String word, int sizeFrom, int size) {
		List<News> list = new ArrayList<News>();

		// 渚濇嵁鏌ヨ绱㈠紩搴撳悕绉板垱寤烘煡璇㈢储寮�
		SearchRequestBuilder searchRequestBuilder = SearchClientFactory.getClient().prepareSearch(INDEXNAME);
		/**
		 * 鏌ヨ绫诲瀷 DFS_QUERY_THEN_FETCH 绮剧‘鏌ヨ SCA 鎵弿鏌ヨ,鏃犲簭
		 */
		searchRequestBuilder.setSearchType(SearchType.DFS_QUERY_THEN_FETCH);
		// 璁剧疆鏌ヨ鏉′欢
		searchRequestBuilder.setQuery(QueryBuilders.termQuery("content", word));
		
		/**
		 * 璁剧疆楂樹寒
		 */
		searchRequestBuilder.addHighlightedField("content").setHighlighterPreTags("<span style=\"color:red\">")
				.setHighlighterPostTags("</span>");

		// Field field=new Field("");

		// 鍒嗛〉搴旂敤
		searchRequestBuilder.setFrom(sizeFrom).setSize(size);
		// 璁剧疆鏄惁鎸夋煡璇㈠尮閰嶅害鎺掑簭
		searchRequestBuilder.setExplain(true);
		// 鎵ц鎼滅储,杩斿洖鎼滅储鍝嶅簲淇℃伅
		SearchResponse response = searchRequestBuilder.execute().actionGet();
		SearchHits searchHits = response.getHits();
		SearchHit[] hits = searchHits.getHits();
		
		for (SearchHit hit : hits) {
			String json = hit.getSourceAsString();
			ObjectMapper mapper = new ObjectMapper();
			try {
				News news = mapper.readValue(json, News.class);
				list.add(news);
			} catch (JsonParseException e) {
				e.printStackTrace();
			} catch (JsonMappingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return list;
	}

	/**
	 * 鎸夌収澶氫釜ID鎼滅储
	 * 
	 * @param IdList
	 * @param sizeFrom
	 * @param size
	 * @return
	 */
	public List<News> SearchByCrawlIds(List<Integer> IdList, int sizeFrom, int size) {
		List<News> list = new ArrayList<News>();

		// 渚濇嵁鏌ヨ绱㈠紩搴撳悕绉板垱寤烘煡璇㈢储寮�
		SearchRequestBuilder searchRequestBuilder = SearchClientFactory.getClient().prepareSearch(INDEXNAME);
		/**
		 * 鏌ヨ绫诲瀷 DFS_QUERY_THEN_FETCH 绮剧‘鏌ヨ SCA 鎵弿鏌ヨ,鏃犲簭
		 */
		searchRequestBuilder.setSearchType(SearchType.DFS_QUERY_THEN_FETCH);
		// 璁剧疆鏌ヨ鏉′欢
		// searchRequestBuilder.setQuery(QueryBuilders.inQuery("crawl_id",
		// IdList));
		searchRequestBuilder.setQuery(QueryBuilders.termsQuery("crawl_id", IdList));
		// 鍒嗛〉搴旂敤
		searchRequestBuilder.setFrom(sizeFrom).setSize(size);
		// 璁剧疆鏄惁鎸夋煡璇㈠尮閰嶅害鎺掑簭
		searchRequestBuilder.setExplain(true);
		// 鎵ц鎼滅储,杩斿洖鎼滅储鍝嶅簲淇℃伅
		SearchResponse response = searchRequestBuilder.execute().actionGet();
		SearchHits searchHits = response.getHits();
		SearchHit[] hits = searchHits.getHits();

		for (SearchHit hit : hits) {
			String json = hit.getSourceAsString();
			ObjectMapper mapper = new ObjectMapper();
			try {
				News news = mapper.readValue(json, News.class);
				list.add(news);
			} catch (JsonParseException e) {
				e.printStackTrace();
			} catch (JsonMappingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return list;
	}

	/**
	 * 鎸夌収澶氫釜ID鎼滅储锛岀粨鏋滄寜鏃堕棿鍊掑簭鎺掑垪
	 * 
	 * @param IdList
	 * @param sizeFrom
	 * @param size
	 * @return
	 */
	public List<News> SearchByCrawlIdsOrderByCrawlTime(List<Integer> IdList, int sizeFrom, int size) {
		List<News> list = new ArrayList<News>();

		// 渚濇嵁鏌ヨ绱㈠紩搴撳悕绉板垱寤烘煡璇㈢储寮�
		SearchRequestBuilder searchRequestBuilder = SearchClientFactory.getClient().prepareSearch(INDEXNAME);
		/**
		 * 鏌ヨ绫诲瀷 DFS_QUERY_THEN_FETCH 绮剧‘鏌ヨ SCA 鎵弿鏌ヨ,鏃犲簭
		 */
		searchRequestBuilder.setSearchType(SearchType.DFS_QUERY_THEN_FETCH);
		// 璁剧疆鏌ヨ鏉′欢
		searchRequestBuilder.setQuery(QueryBuilders.inQuery("crawl_id", IdList));
		// 鍒嗛〉搴旂敤
		searchRequestBuilder.setFrom(sizeFrom).setSize(size);
		// 璁剧疆鏄惁鎸夋煡璇㈠尮閰嶅害鎺掑簭
		searchRequestBuilder.setExplain(true);

		// 鎸夌収鏃堕棿闄嶅簭
		searchRequestBuilder.addSort("crawlDate", SortOrder.DESC);

		// 鎵ц鎼滅储,杩斿洖鎼滅储鍝嶅簲淇℃伅
		SearchResponse response = searchRequestBuilder.execute().actionGet();
		SearchHits searchHits = response.getHits();
		SearchHit[] hits = searchHits.getHits();

		for (SearchHit hit : hits) {
			String json = hit.getSourceAsString();
			ObjectMapper mapper = new ObjectMapper();
			try {
				News news = mapper.readValue(json, News.class);
				list.add(news);
			} catch (JsonParseException e) {
				e.printStackTrace();
			} catch (JsonMappingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return list;
	}

	public List<News> SearchMoreLikeByNews() {
		List<News> list = new ArrayList<News>();
		MoreLikeThisRequestBuilder mlt = new MoreLikeThisRequestBuilder(SearchClientFactory.getClient(), INDEXNAME,
				"news", "AUzFR9G2Dw538fjaW703");
		mlt.setField("content");// 鍖归厤鐨勫瓧娈�
		SearchResponse response = SearchClientFactory.getClient().moreLikeThis(mlt.request()).actionGet();

		SearchHits searchHits = response.getHits();
		SearchHit[] hits = searchHits.getHits();

		for (SearchHit hit : hits) {
			String json = hit.getSourceAsString();
			ObjectMapper mapper = new ObjectMapper();
			try {
				News news = mapper.readValue(json, News.class);
				list.add(news);
			} catch (JsonParseException e) {
				e.printStackTrace();
			} catch (JsonMappingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return list;
	}

	/**
	 * 鎸夌収鍗曚釜ID鏌ヨ
	 * 
	 * @param crawl_id
	 * @return
	 */
	public News SearchByCrawlId(int crawl_id) {
		// 渚濇嵁鏌ヨ绱㈠紩搴撳悕绉板垱寤烘煡璇㈢储寮�
		SearchRequestBuilder searchRequestBuilder = SearchClientFactory.getClient().prepareSearch(INDEXNAME);
		/**
		 * 鏌ヨ绫诲瀷 DFS_QUERY_THEN_FETCH 绮剧‘鏌ヨ SCA 鎵弿鏌ヨ,鏃犲簭
		 */
		searchRequestBuilder.setSearchType(SearchType.DFS_QUERY_THEN_FETCH);
		// 璁剧疆鏌ヨ鏉′欢
		searchRequestBuilder.setQuery(QueryBuilders.termQuery("crawl_id", crawl_id));

		// 璁剧疆鏄惁鎸夋煡璇㈠尮閰嶅害鎺掑簭
		searchRequestBuilder.setExplain(true);
		// 鎵ц鎼滅储,杩斿洖鎼滅储鍝嶅簲淇℃伅
		SearchResponse response = searchRequestBuilder.execute().actionGet();
		SearchHits searchHits = response.getHits();
		SearchHit[] hits = searchHits.getHits();
		String json = hits[0].getSourceAsString();
		ObjectMapper mapper = new ObjectMapper();

		try {
			News news = mapper.readValue(json, News.class);
			return news;
		} catch (JsonParseException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public List<News> searchBySript(String str) {
		List<News> list = new ArrayList<News>();

		// 渚濇嵁鏌ヨ绱㈠紩搴撳悕绉板垱寤烘煡璇㈢储寮�
		SearchRequestBuilder searchRequestBuilder = SearchClientFactory.getClient().prepareSearch(INDEXNAME);
		/**
		 * 鏌ヨ绫诲瀷 DFS_QUERY_THEN_FETCH 绮剧‘鏌ヨ SCA 鎵弿鏌ヨ,鏃犲簭
		 */
		searchRequestBuilder.setSearchType(SearchType.DFS_QUERY_THEN_FETCH);
		// 璁剧疆鏌ヨ鏉′欢
		// searchRequestBuilder.setQuery(QueryBuilders.);
		// 鍒嗛〉搴旂敤
		// searchRequestBuilder.setFrom(sizeFrom).setSize(size);
		// 璁剧疆鏄惁鎸夋煡璇㈠尮閰嶅害鎺掑簭
		searchRequestBuilder.setExplain(true);

		// searchRequestBuilder.addScriptField(name, script, params)

		// 鎸夌収鏃堕棿闄嶅簭
		searchRequestBuilder.addSort("crawlDate", SortOrder.DESC);

		// 鎵ц鎼滅储,杩斿洖鎼滅储鍝嶅簲淇℃伅
		SearchResponse response = searchRequestBuilder.execute().actionGet();
		SearchHits searchHits = response.getHits();
		SearchHit[] hits = searchHits.getHits();

		for (SearchHit hit : hits) {
			String json = hit.getSourceAsString();
			ObjectMapper mapper = new ObjectMapper();
			try {
				News news = mapper.readValue(json, News.class);
				list.add(news);
			} catch (JsonParseException e) {
				e.printStackTrace();
			} catch (JsonMappingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return list;
	}

	public List<News> SearchByMultiCondition(String contentWord, String keyword, String tagName, Integer f, Integer size) {
		List<News> list = new ArrayList<News>();
		// 渚濇嵁鏌ヨ绱㈠紩搴撳悕绉板垱寤烘煡璇㈢储寮�
		SearchRequestBuilder searchRequestBuilder = SearchClientFactory.getClient().prepareSearch(INDEXNAME);

		/**
		 * 鏌ヨ绫诲瀷 DFS_QUERY_THEN_FETCH 绮剧‘鏌ヨ SCA 鎵弿鏌ヨ,鏃犲簭
		 */
		searchRequestBuilder.setSearchType(SearchType.DFS_QUERY_THEN_FETCH);

		BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

		if (contentWord != null) {
			boolQueryBuilder.must(QueryBuilders.termQuery("content", contentWord));
		}
		if (tagName != null) {
			boolQueryBuilder.must(QueryBuilders.termQuery("tagName", tagName));
		}
		if (keyword != null) {
			boolQueryBuilder.must(QueryBuilders.termQuery("keyWords", keyword));
		}

		// 璁剧疆鏌ヨ鏉′欢
		searchRequestBuilder.setQuery(boolQueryBuilder);

		// 鍒嗛〉搴旂敤
		searchRequestBuilder.setFrom(f).setSize(size);
		// 璁剧疆鏄惁鎸夋煡璇㈠尮閰嶅害鎺掑簭
		searchRequestBuilder.setExplain(true);

		// 鎸夌収鏃堕棿闄嶅簭
		searchRequestBuilder.addSort("crawlDate", SortOrder.DESC);

		// 鎵ц鎼滅储,杩斿洖鎼滅储鍝嶅簲淇℃伅
		SearchResponse response = searchRequestBuilder.execute().actionGet();
		SearchHits searchHits = response.getHits();
		SearchHit[] hits = searchHits.getHits();

		for (SearchHit hit : hits) {
			String json = hit.getSourceAsString();
			ObjectMapper mapper = new ObjectMapper();
			try {
				News news = mapper.readValue(json, News.class);
				list.add(news);
			} catch (JsonParseException e) {
				e.printStackTrace();
			} catch (JsonMappingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return list;
	}
}
